<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2019/3/19
 * Time: 23:08
 */
/*****************************无限极分类************************************/
/**
 * 把返回的数据集转换成Tree
 * @param array $list 要转换的数据集
 * @param string $id
 * @param string $pid parent标记字段
 * @param string $child 新增的字段 用来标记child
 * @param int $root 顶级分类的父级pid
 * @return array
 */
function list2tree($list, $pk = 'id', $pid = 'pid', $child = '_child', $root = 0)
{
    // 创建Tree
    $tree = array();

    if (is_array($list)) {

        // 创建基于主键的数组引用
        $refer = array();
        foreach ($list as $key => $val) {
            $refer[$val[$pk]] =& $list[$key];
        }


        foreach ($list as $key => $val) {
            // 判断是否存在parent
            $parentId = $val[$pid];
            if ($root == $parentId) {
                $tree[] =& $list[$key];
            } else {
                if (isset($refer[$parentId])) {
                    $parent =& $refer[$parentId];
                    $parent[$child][] =& $list[$key];
                }
            }
        }
    }
    return $tree;
}

/**
 * 将list2tree的树还原成列表
 * @param  array $tree 原来的树
 * @param  string $child 孩子节点的键
 * @param  string $order 排序显示的键，一般是主键 升序排列
 * @param  array $list 过渡用的中间数组，
 * @return array        返回排过序的列表数组
 */
function tree2list($tree, $child = '_child', $order = 'id', &$list = array())
{
    if (is_array($tree)) {
        $refer = array();
        foreach ($tree as $key => $value) {
            $reffer = $value;
            if (isset($reffer[$child])) {
                unset($reffer[$child]);
                tree2list($value[$child], $child, $order, $list);
            }
            $list[] = $reffer;
        }
//        if (listSortBy($list, $order, 'asc')) {
//            return $list;
//        } else {
//            return false;
//        }
        return $list = listSortBy($list, $order, 'asc');
    } else {
        return false;
    }
}

/**
 * 返回一维数组 增加缩进和级别字段
 * @param array $cate 要递归的数组
 * @param string $html 子级分类前要显示的缩进符号。默认 '─'
 * @param integer $pid 父级分类ID。默认为 0，表示顶级分类
 * @param integer $level level级，配合 $html 显示足够的缩进。默认为 1，表示顶级分类
 * @param string $pidName parent标记字段名
 * @param string $pkName child标记字段名
 * @return array
 */
function unlimitedForLevel($cate, $html = '─', $pid = 0, $level = 1, $pidName = 'pid', $pkName = 'id')
{
    $arr = array();
    foreach ($cate as $v) {
        if ($v[$pidName] == $pid) {
            $v['level'] = $level;
            $v['html'] = str_repeat($html, $level - 1);
            $arr[] = $v;
            $arr = array_merge($arr, unlimitedForLevel($cate, $html, $v[$pkName], $level + 1));
        }
    }
    return $arr;
}

/**
 * 传递父级分类ID返回所有子级分类
 * @param array $cate 要递归的数组
 * @param integer $pid 父级分类ID
 * @param string $pidName parent标记字段名
 * @param string $pkName child标记字段名
 * @return array 返回list数组
 */
function getChildren($cate, $pid, $pidName = 'pid', $pkName = 'id')
{
    $arr = array();
    foreach ($cate as $v) {
        if ($v[$pidName] == $pid) {
            $arr[] = $v;
            $arr = array_merge($arr, getChildren($cate, $v[$pkName]));
        }
    }
    return $arr;
}

/**
 * 传递父级分类ID返回所有子分类ID
 * @param array $cate 要递归的数组
 * @param integer $pid 父级分类ID
 * @param string $pidName parent标记字段名
 * @param string $pkName child标记字段名
 * @return array
 */
function getChildrenId($cate, $pid, $pidName = 'pid', $pkName = 'id')
{
    $arr = array();
    foreach ($cate as $v) {
        if ($v[$pidName] == $pid) {
            $arr[] = $v['id'];
            $arr = array_merge($arr, getChildrenId($cate, $v[$pkName]));
        }
    }
    return $arr;
}

/**
 * 传递子分类ID返回所有父级分类
 * @param array $cate 要递归的数组
 * @param integer $id 子分类ID
 * @param string $pidName parent标记字段名
 * @param string $pkName child标记字段名
 * @return array
 */
function getParents($cate, $id, $pidName = 'pid', $pkName = 'id')
{
    $arr = array();
    foreach ($cate as $v) {
        if ($v[$pkName] == $id) {
            $arr[] = $v;
            $arr = array_merge(getParents($cate, $v[$pidName]), $arr);
        }
    }
    return $arr;
}